<!DOCTYPE html>
<html>
<head>
	<title>SoundJS: Audio Sprite</title>

	<link href="../_assets/css/shared.css" rel="stylesheet" type="text/css"/>
	<link href="../_assets/css/examples.css" rel="stylesheet" type="text/css"/>
	<link href="../_assets/css/soundjs.css" rel="stylesheet" type="text/css"/>
</head>

<body onload="init()">

<header  class="SoundJS">
	<h1>Audio Sprite Example</h1>

	<p>This example shows the usage of an audio sprite.</p>
</header>

<div id="content" class="content" style="height: auto">
	<p id="status">Hello World.</p>
</div>

<div id="error">
	<h2>Sorry!</h2>

	<p>SoundJS is not currently supported in your browser.</p>

	<p>Please <a href="http://github.com/CreateJS/SoundJS/issues" target="_blank">log a bug</a>
		with the device and browser you are using. Thank you.</p>
</div>

<script type="text/javascript" src="../lib/soundjs-NEXT.js"></script>
<!-- We also provide hosted minified versions of all CreateJS libraries.
	http://code.createjs.com -->

<style>
	.red {
		color:red;
		font-size:large;
	}
	.blue {
		color:#0b93d5;
		font-size:small;
	}
	.orange {
		color:orange;
		font-size:xx-large;

	}
</style>
<script id="editable">
	var displayMessage;		// the HTML element we use to display messages to the user

	function init() {
		// store this off because walking the DOM to get the reference is expensive
		displayMessage = document.getElementById("status");

		// if this is on mobile, sounds need to be played inside of a touch event
		if (createjs.BrowserDetect.isIOS || createjs.BrowserDetect.isAndroid || createjs.BrowserDetect.isBlackberry) {
			//document.addEventListener("click", handleTouch, false);	// works on Android, does not work on iOS
			displayMessage.addEventListener("click", handleTouch, false);	// works on Android and iPad
			displayMessage.innerHTML = "Touch to Start";
		}
		else {
			handleTouch(null);
		}
	}

	// launch the app inside of this scope
	function handleTouch(event) {
		displayMessage.removeEventListener("click", handleTouch, false);
		// launch the app by creating it
		var thisApp = new myNameSpace.MyApp();
	}

	// create a namespace for the application
	this.myNameSpace = this.myNameSpace || {};

	// this is a function closure
	(function () {
		// the application
		function MyApp() {
			this.init();
		}

		MyApp.prototype = {
			MAX_LOOPS: 3,		// used to set the max number of audio loops

			displayStatus: null,  // the HTML element we use to display messages to the user
			src: null,         	// the audio src we are trying to play
			soundInstance: null,	// the soundInstance returned by Sound when we create or play a src
			loops: null,			// number of times to loop audio
			currentStep: null,	// current step in the audio process
			sprite: null,
			loadProxy: null,
			loopProxy: null,

			init: function () {
				// store the DOM element so we do repeatedly pay the cost to look it up
				this.displayStatus = document.getElementById("status");

				//enable HTML Audio on iOS
				createjs.HTMLAudioPlugin.enableIOS = true;

				// this does two things, it initializes the default plugins, and if that fails the if statement triggers and we display an error
				// NOTE that WebAudioPlugin plays an empty sound when initialized, which activates web audio on iOS if played inside of a function with a touch event in its callstack
				if (!createjs.Sound.initializeDefaultPlugins()) {
					document.getElementById("error").style.display = "block";
					document.getElementById("content").style.display = "none";
					return;
				}

				this.sprite = [
				    {id:"pew", class:"blue"},
					{id:"hit", class:"red"},
					{id:"explode", class:"orange"}
				];	// this code is not needed for sprites, it is used for the looping effect
				var assetsPath = "../_assets/audio/";
				var sounds = [
					// This is an audio sprite.  The sprite property tells SoundJS what ids to use for playback, with time to start playback and length of playback
					// we are setting data to 1 to show how sprites function with only a single instance
					{src: "Game-AudioSprite.ogg", data: {channels: 1,
						audioSprite: [
							{id: "hit", startTime: 0, duration: 500},
							{id: "pew", startTime: 1000, duration: 400},
							{id: "explode", startTime: 1700, duration: 1074}
						]}
					}
				];

				this.displayStatus.innerHTML = "Waiting for load to complete.";  // let the user know what's happening
				// NOTE createjs.proxy is used to apply scope so we stay within the touch scope, allowing sound to play on mobile devices
				this.loadProxy = createjs.proxy(this.handleLoad, this);
				createjs.Sound.alternateExtensions = ["mp3"];	// add other extensions to try loading if the src file extension is not supported
				createjs.Sound.addEventListener("fileload", this.loadProxy); // add event listener for when load is completed.
				createjs.Sound.registerSounds(sounds, assetsPath);  // register sounds, which preloads by default

				return this;
			},

			// play a sound inside
			handleLoad: function (event) {
				this.displayStatus.innerHTML = "Load Complete, time to kickoff playback.";  // let the user know what we are playing
				createjs.Sound.removeEventListener("fileload", this.loadProxy);	// we only load 1 sound, so remove the listener

				this.loopProxy = createjs.proxy(this.handleLoop, this);
				this.launchLoop();
			},

			// kickoff our audio loop
			launchLoop: function () {
				this.currentStep = 0;
				this.loops = Math.floor((Math.random() * this.MAX_LOOPS));	// random between 0 and MAX_LOOPS -1

				var spriteData = this.sprite[this.currentStep];

				this.soundInstance = createjs.Sound.play(spriteData.id, {loop: this.loops});
				this.soundInstance.addEventListener("loop", this.loopProxy);
				this.soundInstance.addEventListener("complete", createjs.proxy(this.nextAudioRelay, this));
				this.displayStatus.innerHTML = '<div class='+spriteData.class+'>'+spriteData.id+'</div>';
			},

			// update display text
			handleLoop: function () {
			    var spriteData = this.sprite[this.currentStep];
				this.displayStatus.innerHTML = this.displayStatus.innerHTML + " " + '<div id="effect" class='+spriteData.class+'>'+spriteData.id+'</div>';
			},

			// kick off delayed next step of audio loop
			nextAudioRelay: function () {
				var next = this.currentStep == 0 ? this.delayedNextAudio : this.launchLoop;
				setTimeout(createjs.proxy(next, this), 1000 + this.currentStep * 200);
			},

			delayedNextAudio: function () {
				this.currentStep++;

				var spriteData = this.sprite[this.currentStep];

				this.soundInstance = createjs.Sound.play(spriteData.id, {loop: this.loops});
				this.soundInstance.addEventListener("loop", this.loopProxy);
				this.soundInstance.addEventListener("complete", createjs.proxy(this.handleFinalAudio, this));
				this.displayStatus.innerHTML = '<div class='+spriteData.class+'>'+spriteData.id+'</div>';
			},

			// final step of audio loop
			handleFinalAudio: function () {
				this.currentStep++;
				this.soundInstance = createjs.Sound.play(this.sprite[this.currentStep].id);
				this.soundInstance.addEventListener("complete", createjs.proxy(this.nextAudioRelay, this));
				this.handleLoop();

			}
		}

		// add MyApp to myNameSpace
		myNameSpace.MyApp = MyApp;
	}());

</script>

</body>
</html>
